#include "../ocl/types.h"

FILE * ocl_logfile = NULL;
cl_int ocl_errno   = CL_SUCCESS;

#define OCL_STRERR(X) X

const char * ocl_strerror(const cl_int err)
{
	switch (err) {
		case CL_SUCCESS:                          return OCL_STRERR("Success!");
		case CL_DEVICE_NOT_FOUND:                 return OCL_STRERR("Device not found.");
		case CL_DEVICE_NOT_AVAILABLE:             return OCL_STRERR("Device not available");
		case CL_COMPILER_NOT_AVAILABLE:           return OCL_STRERR("Compiler not available");
		case CL_MEM_OBJECT_ALLOCATION_FAILURE:    return OCL_STRERR("Memory object allocation failure");
		case CL_OUT_OF_RESOURCES:                 return OCL_STRERR("Out of resources");
		case CL_OUT_OF_HOST_MEMORY:               return OCL_STRERR("Out of host memory");
		case CL_PROFILING_INFO_NOT_AVAILABLE:     return OCL_STRERR("Profiling information not available");
		case CL_MEM_COPY_OVERLAP:                 return OCL_STRERR("Memory copy overlap");
		case CL_IMAGE_FORMAT_MISMATCH:            return OCL_STRERR("Image format mismatch");
		case CL_IMAGE_FORMAT_NOT_SUPPORTED:       return OCL_STRERR("Image format not supported");
		case CL_BUILD_PROGRAM_FAILURE:            return OCL_STRERR("Program build failure");
		case CL_MAP_FAILURE:                      return OCL_STRERR("Map failure");
		case CL_INVALID_VALUE:                    return OCL_STRERR("Invalid value");
		case CL_INVALID_DEVICE_TYPE:              return OCL_STRERR("Invalid device type");
		case CL_INVALID_PLATFORM:                 return OCL_STRERR("Invalid platform");
		case CL_INVALID_DEVICE:                   return OCL_STRERR("Invalid device");
		case CL_INVALID_CONTEXT:                  return OCL_STRERR("Invalid context");
		case CL_INVALID_QUEUE_PROPERTIES:         return OCL_STRERR("Invalid queue properties");
		case CL_INVALID_COMMAND_QUEUE:            return OCL_STRERR("Invalid command queue");
		case CL_INVALID_HOST_PTR:                 return OCL_STRERR("Invalid host pointer");
		case CL_INVALID_MEM_OBJECT:               return OCL_STRERR("Invalid memory object");
		case CL_INVALID_IMAGE_FORMAT_DESCRIPTOR:  return OCL_STRERR("Invalid image format descriptor");
		case CL_INVALID_IMAGE_SIZE:               return OCL_STRERR("Invalid image size");
		case CL_INVALID_SAMPLER:                  return OCL_STRERR("Invalid sampler");
		case CL_INVALID_BINARY:                   return OCL_STRERR("Invalid binary");
		case CL_INVALID_BUILD_OPTIONS:            return OCL_STRERR("Invalid build options");
		case CL_INVALID_PROGRAM:                  return OCL_STRERR("Invalid program");
		case CL_INVALID_PROGRAM_EXECUTABLE:       return OCL_STRERR("Invalid program executable");
		case CL_INVALID_KERNEL_NAME:              return OCL_STRERR("Invalid kernel name");
		case CL_INVALID_KERNEL_DEFINITION:        return OCL_STRERR("Invalid kernel definition");
		case CL_INVALID_KERNEL:                   return OCL_STRERR("Invalid kernel");
		case CL_INVALID_ARG_INDEX:                return OCL_STRERR("Invalid argument index");
		case CL_INVALID_ARG_VALUE:                return OCL_STRERR("Invalid argument value");
		case CL_INVALID_ARG_SIZE:                 return OCL_STRERR("Invalid argument size");
		case CL_INVALID_KERNEL_ARGS:              return OCL_STRERR("Invalid kernel arguments");
		case CL_INVALID_WORK_DIMENSION:           return OCL_STRERR("Invalid work dimension");
		case CL_INVALID_WORK_GROUP_SIZE:          return OCL_STRERR("Invalid work group size");
		case CL_INVALID_WORK_ITEM_SIZE:           return OCL_STRERR("Invalid work item size");
		case CL_INVALID_GLOBAL_OFFSET:            return OCL_STRERR("Invalid global offset");
		case CL_INVALID_EVENT_WAIT_LIST:          return OCL_STRERR("Invalid event wait list");
		case CL_INVALID_EVENT:                    return OCL_STRERR("Invalid event");
		case CL_INVALID_OPERATION:                return OCL_STRERR("Invalid operation");
		case CL_INVALID_GL_OBJECT:                return OCL_STRERR("Invalid OpenGL object");
		case CL_INVALID_BUFFER_SIZE:              return OCL_STRERR("Invalid buffer size");
		case CL_INVALID_MIP_LEVEL:                return OCL_STRERR("Invalid mip-map level");
		default:                                  return OCL_STRERR("Unknown");
	}
}

#include <stdarg.h>

void ocl_perror(FILE *fp, const char *when,...) 
{
	va_list ap;
	assert( when != NULL );
	assert( fp   != NULL );
	if( CL_SUCCESS == ocl_errno )
	{
		fprintf( fp, "**[LibC] '%s': ", strerror(errno) );
	}
	else
	{
		fprintf( fp, "**[OpenCL] '%s' : ", ocl_strerror(ocl_errno) );
	}

	va_start(ap,when);
	vfprintf(fp,when, ap);
	va_end(ap);
	fprintf(fp, "\n");
}

